﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NNote.Properties;
using System.IO;
using NNote.DocumentModel;

namespace NNote {
	public partial class MainForm : Form {
		public MainForm() {
			InitializeComponent();
			command_File_New.Activate(new CancelEventArgs(false));
		}

		IDocumentViewer documentView;
		Document document;

		private void ShowView(IDocumentViewer view) {
			var control = view.Control;
			control.Dock = DockStyle.Fill;
			toolStripContainer1.ContentPanel.Controls.Add(control);
			var document = view.Document;
			document.TitleChanged += new EventHandler(document_TitleChanged);
			document.ModifiedChanged += new EventHandler(document_ModifiedChanged);
			documentView.SelectionChanged += new EventHandler(documentView_SelectionChanged);
			documentView.RedoChanged += new EventHandler(documentView_RedoChanged);
			documentView.UndoChanged += new EventHandler(documentView_UndoChanged);

			document_TitleChanged(document, EventArgs.Empty);
			document_ModifiedChanged(document, EventArgs.Empty);
			documentView_SelectionChanged(documentView, EventArgs.Empty);

			documentView_UndoChanged(documentView, EventArgs.Empty);
			documentView_RedoChanged(documentView, EventArgs.Empty);
		}
		private void HideView(IDocumentViewer view) {
			var control = view.Control;
			toolStripContainer1.ContentPanel.Controls.Remove(control);
			var document = view.Document;
			document.TitleChanged -= new EventHandler(document_TitleChanged);
			document.ModifiedChanged -= new EventHandler(document_ModifiedChanged);
			documentView.SelectionChanged -= new EventHandler(documentView_SelectionChanged);
			documentView.RedoChanged -= new EventHandler(documentView_RedoChanged);
			documentView.UndoChanged -= new EventHandler(documentView_UndoChanged);
		}
		private void SetTitle(Document document) {
			this.Text = string.Format(
				"{0}{1} - NNote",
				document.Title,
				document.Modified ? "*" : ""
			);
		}

		void document_ModifiedChanged(object sender, EventArgs e) {
			var document = (Document)sender;
			SetTitle(document);
			command_File_Save.Enabled =
				document.Modified;
		}
		void document_TitleChanged(object sender, EventArgs e) {
			var document = (Document)sender;
			SetTitle(document);
		}

		void documentView_SelectionChanged(object sender, EventArgs e) {
			command_Edit_Copy.Enabled =
				command_Edit_Cut.Enabled =
					documentView.SelectionLength > 0;
		}
		void documentView_UndoChanged(object sender, EventArgs e) {
			command_Edit_Undo.Enabled = documentView.CanUndo;
			if (command_Edit_Undo.Enabled) {
				command_Edit_Undo.ToolTipText = string.Format("Undo: {0}", documentView.UndoActionName);
			} else {
				command_Edit_Undo.ToolTipText = "Undo: Nothing";
			}
		}
		void documentView_RedoChanged(object sender, EventArgs e) {
			command_Edit_Redo.Enabled = documentView.CanRedo;
			if (command_Edit_Redo.Enabled) {
				command_Edit_Redo.ToolTipText = string.Format("Redo: {0}", documentView.RedoActionName);
			} else {
				command_Edit_Redo.ToolTipText = "Redo: Nothing";
			}
		}

		private void clipboardNotifier1_ClipboardChanged(object sender, EventArgs e) {
			var obj = Clipboard.GetDataObject();
			var haveFormats = obj.GetFormats();
			var canFormats = documentView.GetSupportedClipboardFormats();
			var possible = haveFormats.Intersect(canFormats);
			command_Edit_Paste.Enabled = possible.Any();
		}

		private void command_File_New_Activate(object sender, CancelEventArgs e) {
			command_File_Close.Activate(e);
			if (!e.Cancel) {
				document = new Document();
				documentView = new PlainTextEditor(document);
				ShowView(documentView);
			}
		}
		private void command_File_Open_Activate(object sender, CancelEventArgs e) {
			command_File_Close.Activate(e);
			if (!e.Cancel) {
				if (openFileDialog1.ShowDialog(this) == DialogResult.Cancel) {
					e.Cancel = true;
					return;
				}
				document = Document.FromFile(openFileDialog1.FileName);
				documentView = new PlainTextEditor(document);
				ShowView(documentView);
			}
		}
		private void command_File_Close_Activated(object sender, CancelEventArgs e) {
			if (document != null && document.Modified) {
				var result = new CloseFileDialog(document).ShowDialog(this);
				switch (result) {
					case DialogResult.Yes: // Save the file
						command_File_Save.Activate(e);
						break;
					case DialogResult.No: // Do not save.
						break;
					case DialogResult.Cancel: // Cancel the operation
						e.Cancel = true;
						return;
					default:
						throw new NotSupportedException();
				}
			}
			if (documentView != null)
				HideView(documentView);
		}
		private void command_File_Save_Activated(object sender, CancelEventArgs e) {
			if (document.Filename == null) {
				command_File_SaveAs.Activate(e);
			} else {
				document.Save();
			}
		}
		private void command_File_SaveAs_Activated(object sender, CancelEventArgs e) {
			var result = saveFileDialog1.ShowDialog(this);
			if (result == DialogResult.Cancel) {
				e.Cancel = true;
				return;
			}
			document.SaveAs(saveFileDialog1.FileName);
		}

		private void command_Application_Exit_Activated(object sender, CancelEventArgs e) {
			//var e = new CancelEventArgs();
			//command_File_Close.Activate(e);
			//if (!e.Cancel)
			this.Close();
		}

		private void command_View_WordWrap_Activated(object sender, CancelEventArgs e) {
			Settings.Default.WordWrap = command_View_WordWrap.Checked;
			documentView.OnSettingsChanged();
		}

		private void command_Edit_Cut_Activated(object sender, CancelEventArgs e) {
			documentView.Cut();
		}
		private void command_Edit_Copy_Activated(object sender, CancelEventArgs e) {
			documentView.Copy();
		}
		private void command_Edit_Paste_Activated(object sender, CancelEventArgs e) {
			documentView.Paste();
		}
		private void command_Edit_Undo_Activated(object sender, CancelEventArgs e) {
			documentView.Undo();
		}
		private void command_Edit_Redo_Activated(object sender, CancelEventArgs e) {
			documentView.Redo();
		}

		private void command_Tools_Options_Activated(object sender, CancelEventArgs e) {
			if (new OptionsDialog().ShowDialog(this) == DialogResult.OK)
				documentView.OnSettingsChanged();
		}

		private void command_Edit_SelectAll_Activated(object sender, CancelEventArgs e) {
			documentView.SelectAll();
		}
	}
}
